<?php
/**
 * 异步客户端
 *  ptc客户端 php client_sync.php
 *  udp客户端 php client_sync.php udp
 *  实现机制
 *  while主进程程 阻塞
 *  协程接收服务端数据
 */
use Swoole\Coroutine;
use Swoole\Coroutine\Channel;
use Swoole\Coroutine\Socket;

$sock_type = SOCK_STREAM;
if (isset($argv[1]) && 'udp' == $argv[1]) $sock_type = SOCK_DGRAM;

Swoole\Coroutine\run(function () use($sock_type) {
    $host = '127.0.0.1'; // 服务器地址
    $port = 9503;        // 服务器端口

// 创建协程通道用于用户输入
    $inputChannel = new Channel(1);

    // 启动协程处理用户输入
    Coroutine::create(function () use ($inputChannel) {
        while (true) {
            echo "Enter message to send: ";
            $message = trim(fgets(STDIN));
            $inputChannel->push($message);
        }
    });

    // 创建 TCP/UDP 客户端
    $client = new Socket(AF_INET, $sock_type, 0);
    if (!$client->connect($host, $port, 5)) {
        echo "Failed to connect to server. Error: {$client->errCode}\n";
        return;
    }

    echo "Connected to server at {$host}:{$port}\n";

    // 启动协程接收服务器消息
    Coroutine::create(function () use ($client) {
        while (true) {
            $data = $client->recv();
            if ($data === '' || $data === false) {
                echo "Connection closed by server.\n";
                break;
            }
            echo "Received from server: {$data}\n";
        }
    });

    // 主协程发送数据
    while (true) {
        $message = $inputChannel->pop(); // 从输入通道获取用户输入
        if ($message === 'quit') {
            echo "Closing connection...\n";
            $client->close();
            break;
        }
        $client->send($message . "\n"); // 发送用户输入到服务器
    }
});